package com.itlong.cloud.operate.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Joiner;
import com.itlong.cloud.POJO.DTO.operate.OperateDeviceManageGetPageDTO;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.POJO.VO.common.ProjectIotInfo;
import com.itlong.cloud.POJO.VO.operate.*;
import com.itlong.cloud.POJO.VO.property.PropertyDeviceCloudControllerGetVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppDeviceDao;
import com.itlong.cloud.commons.dao.ICloudTalkPushCloudIntercomChangeLogDao;
import com.itlong.cloud.commons.dao.IPushCloudElevatorChangeLogDao;
import com.itlong.cloud.commons.dao.IPushCloudEntranceChangeLogDao;
import com.itlong.cloud.commons.thread.queue.process.queue.SendIotPushMessageQueue;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.IotCloudCtrlInstructEnum;
import com.itlong.cloud.equip.operate.IOperateDeviceManageServiceClient;
import com.itlong.cloud.iottp.IIotAliOSSServiceClient;
import com.itlong.cloud.operate.dao.IDeviceRunLogDao;
import com.itlong.cloud.operate.dao.IOperateDeviceManageDao;
import com.itlong.cloud.operate.service.IOperateDeviceManageService;
import com.itlong.cloud.property.dao.IDeviceAddressUserInfoServiceDao;
import com.itlong.cloud.property.dao.IDeviceCloudControllerDao;
import com.itlong.cloud.property.dao.IPropertyElevatorDao;
import com.itlong.cloud.property.dao.ITimeTaskAuthDeviceAddressInfoDao;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.smartcard.dao.ISmartCardFaceDao;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.date.DateUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.random.IdWorker;
import com.itlong.cloud.utils.random.LogicIdUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <desc>
 * 运营-项目管理-设备管理服务接口实现类。
 * <desc/>
 *
 * @createDate 2019/01/18.
 */
@Service
public class IOperateDeviceManageServiceImpl implements IOperateDeviceManageService {

    private static final Logger LOG = LoggerFactory.getLogger(IOperateDeviceManageServiceImpl.class);

    @Autowired
    IOperateDeviceManageDao iOperateDeviceManageDao;

    @Autowired
    RedisService redisService;

    @Autowired
    private MessageSender messageSender;

    @Autowired
    private IDeviceRunLogDao iDeviceRunLogDao;

    @Autowired
    IPushCloudElevatorChangeLogDao iPushCloudElevatorChangeLogDao;

    @Autowired
    IAppDeviceDao iAppDeviceDao;

    @Autowired
    SendIotPushMessageQueue sendIotPushMessageQueue;

    @Autowired
    ICloudTalkPushCloudIntercomChangeLogDao iCloudTalkPushCloudIntercomChangeLogDao;

    @Autowired
    IPushCloudEntranceChangeLogDao iPushCloudEntranceChangeLogDao;

    //物业电梯持久层接口
    @Autowired
    private IPropertyElevatorDao iPropertyElevatorDao;

    @Autowired
    ISmartCardFaceDao iSmartCardFaceDao;

    @Autowired
    IDeviceAddressUserInfoServiceDao iDeviceAddressUserInfoServiceDao;

    @Autowired
    IDeviceCloudControllerDao iDeviceCloudControllerDao;

    @Autowired
    ITimeTaskAuthDeviceAddressInfoDao iTimeTaskAuthDeviceAddressInfoDao;

    @Autowired
    PushCloudChangLogMessage queue;

    private ExecutorService cachedThreadPool; //线程池

    private static final IdWorker idWorker = new IdWorker(18);
    @Autowired
    private IIotAliOSSServiceClient iIotAliOSSServiceClient;

    @Value("${" + PlatformConstants.DEVICE_LOG + "}")
    public String DEVICE_LOG;

    /**
     * <desc>
     * 分页获取设备信息。
     * <desc/>
     *
     * @param dto 参数请求对象
     * @return
     * @author Qiang.S
     * @createDate 2019/01/18
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperateDeviceManageInfoAllVO getDeviceByPage(OperateDeviceManageGetPageDTO dto) throws Exception {
        OperateDeviceManageInfoAllVO vo = new OperateDeviceManageInfoAllVO();
        Set<String> resultIntercom = redisService.getKeys(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY) == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY);//云对讲在线设备
        Set<String> resultElevator = redisService.getKeys(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY) == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY);//云电梯在线设备
        Set<String> resultPad = redisService.getKeys(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY) == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY);//平板在线设备
        Set<String> resultEntrance = redisService.getKeys(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY) == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY);//云门禁在线设备
        Set<String> resultCluster = redisService.getKeys(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY) == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY);//云群控器在线设备
        Set<String> resultWippen = redisService.getKeys(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY) == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY);//云联动器在线设备
        Set<String> resultUnibodyFace = redisService.getKeys(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + "*");//一体式人脸识别门禁在线设备
        // Set<String> resultUnibodyEntrance = redisService.getKeys(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + "*");//一体式云门禁在线设备

        // 获取在线设备 过滤不在线设备
        if (resultIntercom.size() > 0) {
            resultIntercom = getOnlineDevice(resultIntercom);
        }
        if (resultElevator.size() > 0) {
            resultElevator = getOnlineDevice(resultElevator);
        }
        if (resultPad.size() > 0) {
            resultPad = getOnlineDevice(resultPad);
        }
        if (resultEntrance.size() > 0) {
            resultEntrance = getOnlineDevice(resultEntrance);
        }
        if (resultCluster.size() > 0) {
            resultCluster = getOnlineDevice(resultCluster);
        }
        if (resultWippen.size() > 0) {
            resultWippen = getOnlineDevice(resultWippen);
        }
        if (resultUnibodyFace.size() > 0) {
            resultUnibodyFace = getOnlineDevice(resultUnibodyFace);
        }

     /*   if (resultUnibodyEntrance.size() > 0){
            resultUnibodyEntrance = getOnlineDevice(resultUnibodyEntrance);
        }*/

        //增加默认排序
        if (StringUtils.isBlank(dto.getOrderColumn()) && StringUtils.isBlank(dto.getMark())) {
            dto.setOrderColumn("createTime");
        }else{
            dto.setOrderColumn("updateTime");
        }
        if (StringUtils.isBlank(dto.getOrderRule())) {
            dto.setOrderColumn("desc");
        }
        if (StringUtils.isNotBlank(dto.getIsOnline())) {
            if (dto.getIsOnline().split(",").length < 3) {
                dto.setIsOnlineList(Arrays.asList(dto.getIsOnline().split(",")));
            }
        }
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(dto);
        //分页类默认pageSize为20
        Page<OperateDeviceManageInfoVO> page = new Page<>();
        page.getPage().setPageSize(dto.getPageSize());
        page.getPage().setCurrentPage(dto.getCurrentPage());
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        params.put("mark", dto.getMark());

        if (dto.getIsOnline() != null && !"".equals(dto.getIsOnline()) && !"-1".equals(dto.getIsOnline())) {
            String[] strResultIntercom = new String[resultIntercom.size()];
            String[] strResultIntercom2 = resultIntercom.toArray(strResultIntercom);
            String[] strResultElevator = new String[resultElevator.size()];
            String[] strResultElevator2 = resultElevator.toArray(strResultElevator);
            String[] strResultPad = new String[resultPad.size()];
            String[] strResultPad2 = resultPad.toArray(strResultPad);
            String[] strResultEntrance = new String[resultEntrance.size()];
            String[] strResultEntrance2 = resultEntrance.toArray(strResultEntrance);
            String[] strResultCluster = new String[resultCluster.size()];
            String[] strResultCluster2 = resultCluster.toArray(strResultCluster);
            String[] strResultWippen = new String[resultWippen.size()];
            String[] strResultWippen2 = resultWippen.toArray(strResultWippen);
            String[] strResultUnibodyFace = new String[resultUnibodyFace.size()];
            String[] strResultUnibodyFace2 = resultUnibodyFace.toArray(strResultUnibodyFace);
         /*   String[] strResultUnibodyEntrance = new String[resultUnibodyEntrance.size()];
            String[] strResultUnibodyEntrance2 = resultUnibodyFace.toArray(strResultUnibodyEntrance);
*/

            for (int i = 0; i < strResultIntercom2.length; i++) {
                strResultIntercom2[i] = strResultIntercom2[i].replace(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY, "");
            }
            for (int i = 0; i < strResultElevator2.length; i++) {
                strResultElevator2[i] = strResultElevator2[i].replace(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY, "");
            }
            for (int i = 0; i < strResultPad2.length; i++) {
                strResultPad2[i] = strResultPad2[i].replace(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY, "");
            }
            for (int i = 0; i < strResultEntrance2.length; i++) {
                strResultEntrance2[i] = strResultEntrance2[i].replace(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY, "");
            }
            for (int i = 0; i < strResultCluster2.length; i++) {
                strResultCluster2[i] = strResultCluster2[i].replace(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY, "");
            }
            for (int i = 0; i < strResultWippen2.length; i++) {
                strResultWippen2[i] = strResultWippen2[i].replace(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY, "");
            }
            for (int i = 0; i < strResultUnibodyFace2.length; i++) {
                strResultUnibodyFace2[i] = strResultUnibodyFace2[i].replace(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY, "");
            }

         /*   for (int i = 0; i < strResultUnibodyEntrance2.length; i++) {
                strResultUnibodyEntrance2[i] = strResultUnibodyEntrance2[i].replace(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY, "");
            }*/


            //无设备类型时
            if (dto.getDeviceType() == null || "".equals(dto.getDeviceType())) {
                String[] newStr = new String[strResultIntercom2.length + strResultElevator2.length + strResultPad2.length + strResultEntrance2.length
                        + strResultCluster2.length + strResultWippen2.length + strResultUnibodyFace2.length];
                for (int x = 0; x < strResultIntercom2.length; x++) {
                    newStr[x] = strResultIntercom2[x];
                }
                for (int y = 0; y < strResultElevator2.length; y++) {
                    newStr[strResultIntercom2.length + y] = strResultElevator2[y];
                }
                for (int z = 0; z < strResultPad2.length; z++) {
                    newStr[strResultIntercom2.length + strResultElevator2.length + z] = strResultPad2[z];
                }
                for (int w = 0; w < strResultEntrance2.length; w++) {
                    newStr[strResultIntercom2.length + strResultElevator2.length + strResultPad2.length + w] = strResultEntrance2[w];
                }
                for (int p = 0; p < strResultCluster2.length; p++) {
                    newStr[strResultIntercom2.length + strResultElevator2.length + strResultPad2.length + strResultEntrance2.length + p] = strResultCluster2[p];
                }
                for (int q = 0; q < strResultWippen2.length; q++) {
                    newStr[strResultIntercom2.length + strResultElevator2.length + strResultPad2.length + strResultEntrance2.length
                            + strResultCluster2.length + q] = strResultWippen2[q];
                }
                for (int o = 0; o < strResultUnibodyFace2.length; o++) {
                    newStr[strResultIntercom2.length + strResultElevator2.length + strResultPad2.length + strResultEntrance2.length
                            + strResultCluster2.length + strResultWippen2.length + o] = strResultUnibodyFace2[o];
                }
             /*   for (int p = 0; p < strResultUnibodyEntrance2.length; p++) {
                    newStr[strResultIntercom2.length + strResultUnibodyEntrance2.length + strResultPad2.length + strResultEntrance2.length
                            + strResultCluster2.length + strResultWippen2.length +strResultUnibodyFace2.length+ p] = strResultUnibodyEntrance2[p];
                }*/


                params.put("deviceUniques", newStr.length == 0 ? new String[]{""} : newStr);
            }
            //设备类型:1云对讲
            if ("1".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultIntercom2.length == 0 ? new String[]{""} : strResultIntercom2);
            }
            //设备类型:2云电梯
            if ("2".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultElevator2.length == 0 ? new String[]{""} : strResultElevator2);
            }
            //设备类型:3人脸平板
            if ("3".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultPad2.length == 0 ? new String[]{""} : strResultPad2);
            }
            //设备类型:4云门禁
            if ("4".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultEntrance2.length == 0 ? new String[]{""} : strResultEntrance2);
            }
            //设备类型:5群控器
            if ("5".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultCluster2.length == 0 ? new String[]{""} : strResultCluster2);
            }
            //设备类型:6联动器
            if ("6".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultWippen2.length == 0 ? new String[]{""} : strResultWippen2);
            }
            //设备类型:7一体式人脸识别门禁
            if ("7".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultUnibodyFace2.length == 0 ? new String[]{""} : strResultUnibodyFace2);
            }

         /*   //设备类型:10一体式云门禁
            if ("10".equals(dto.getDeviceType())) {
                params.put("deviceUniques", strResultUnibodyEntrance2.length == 0 ? new String[]{""} : strResultUnibodyEntrance2);
            }*/
        }
        //填充返回数据集
        List<OperateDeviceManageInfoVO> list;
        int deviceInfoCount = 0;
        if (null != dto.getIsOnlineList() && dto.getIsOnlineList().size() == 2 && dto.getIsOnlineList().contains("-1") && dto.getIsOnlineList().contains("1")) {
            list = iOperateDeviceManageDao.getDeviceInfoPage1(params);
            deviceInfoCount = iOperateDeviceManageDao.getDeviceInfoCount1(params);
        } else {
            list = iOperateDeviceManageDao.getDeviceInfoPage(params);
            deviceInfoCount = iOperateDeviceManageDao.getDeviceInfoCount(params);
        }

        for (OperateDeviceManageInfoVO operateDeviceManageInfoVO : list) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            // 活跃时间
            if (StringUtils.isNotBlank(redisService.get(RedisConstant.DEVICE_NEW_UPDATE_CACHE_TIME + operateDeviceManageInfoVO.getDeviceUnique()))) {
                operateDeviceManageInfoVO.setDeviceActiveTime(sdf.format(new Date(Long.valueOf(redisService.get(RedisConstant.DEVICE_NEW_UPDATE_CACHE_TIME + operateDeviceManageInfoVO.getDeviceUnique())))));
            }

            if ("1".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline(("1".equals(redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique()))
                        || "2".equals(redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique()))) ? "1" : "0");
            }
            if ("2".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }
            if ("3".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique()))
                        || "2".equals(redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }
            if ("4".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }
            if ("5".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }
            if ("6".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }
            if ("7".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }
         /*   if ("10".equals(operateDeviceManageInfoVO.getType())) {
                operateDeviceManageInfoVO.setIsOnline("1".equals(redisService.get(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + operateDeviceManageInfoVO.getDeviceUnique())) ? "1" : "0");
            }*/
        }
        page.setRows(list, deviceInfoCount);
        vo.setPage(page);
        int deviceCount = iOperateDeviceManageDao.getDeviceInfoCountAll(dto.getDeviceType(),dto.getMark());
        int iotDeviceCount = iOperateDeviceManageDao.getIotDeviceInfoCountAll(dto.getDeviceType(),dto.getMark());
        int onlineDevice = 0;
        if (dto != null) {
            if (dto.getDeviceType() == null || "".equals(dto.getDeviceType())) {//全部
                onlineDevice = resultIntercom.size() + resultElevator.size() + resultPad.size() + resultEntrance.size() + resultCluster.size() + resultWippen.size() + resultUnibodyFace.size();
            }
            if ("1".equals(dto.getDeviceType())) {//云对讲
                onlineDevice = resultIntercom.size();
            }
            if ("2".equals(dto.getDeviceType())) {//云电梯
                onlineDevice = resultElevator.size();
            }
            if ("3".equals(dto.getDeviceType())) {//平板
                onlineDevice = resultPad.size();
            }
            if ("4".equals(dto.getDeviceType())) {//云门禁
                onlineDevice = resultEntrance.size();
            }
            if ("5".equals(dto.getDeviceType())) {//群控器
                onlineDevice = resultCluster.size();
            }
            if ("6".equals(dto.getDeviceType())) {//联动器
                onlineDevice = resultWippen.size();
            }
            if ("7".equals(dto.getDeviceType())) {//一体式人脸识别门禁
                onlineDevice = resultUnibodyFace.size();
            }
         /*   if ("10".equals(dto.getDeviceType())) {//一体式云门禁
                onlineDevice = resultUnibodyEntrance.size();
            }*/
        }
        vo.setDeviceCount(deviceCount + "");
        vo.setOnlineDevice(onlineDevice + "");
        vo.setOfflineDevice((iotDeviceCount - onlineDevice) + "");
        return vo;
    }

    /**
     * <desc>
     * 获取在线设备 过滤不在线设备
     * <desc/>
     *
     * @param deviceOnlineSet 设备在线信息
     * @return
     * @author caoshuai
     * @createDate 2020/10/12
     */
    private Set<String> getOnlineDevice(Set<String> deviceOnlineSet) {
        Set<String> intercomSet = new HashSet<>();
        for (String key : deviceOnlineSet) {
            if ("1".equals(redisService.get(key)) || "2".equals(redisService.get(key))) {
                intercomSet.add(key);
            }
        }
        return intercomSet;
    }

    /**
     * <desc>
     * 获取每个设备所占比例及统计在线与离线设备
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate 2019/10/28
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public OperateDeviceManageInfoAllVO getOperateDeviceInfo() throws Exception {
        OperateDeviceManageInfoAllVO operateDeviceManageInfoAllVO = new OperateDeviceManageInfoAllVO();
        Set<String> resultIntercom = redisService.getKeys(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + "*");//云对讲在线设备
        Set<String> resultElevator = redisService.getKeys(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY + "*");//云电梯在线设备
        Set<String> resultPad = redisService.getKeys(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY + "*");//平板在线设备
        Set<String> resultEntrance = redisService.getKeys(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_ENTRANCE_IS_ONLINE_KEY + "*");//云门禁在线设备
        Set<String> resultCluster = redisService.getKeys(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_CLUSTER_IS_ONLINE_KEY + "*");//云群控器在线设备
        Set<String> resultWippen = redisService.getKeys(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_WIPPEN_IS_ONLINE_KEY + "*");//云联动器在线设备
        Set<String> resultUnibodyFace = redisService.getKeys(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + "*") == null ? new HashSet<>() : redisService.getKeys(RedisConstant.DEVICE_UNIBODY_FACE_IS_ONLINE_KEY + "*");//一体式人脸识别门禁在线设备

        List<Map<String, Object>> nameAndCountList = iOperateDeviceManageDao.getEachDeviceCount();
        Integer deviceTotalCount = iOperateDeviceManageDao.getDeviceInfoCount(null);
        List<Map<String, Object>> percentData = new ArrayList<>();
        NumberFormat numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        //计数器
        int counter = 0;
        float presentValue = 0f;
        for (Map<String, Object> nameAndCount : nameAndCountList) {
            counter++;
            if (percentData.size() < 5) {
                String deviceName = nameAndCount.get("deviceName").toString();
                Integer deviceCount = Integer.parseInt(nameAndCount.get("count").toString());
                Map<String, Object> passMap = new HashMap<>();
                float devicePercentValue;
                if (nameAndCountList.size() > 5 || counter != nameAndCountList.size()) {
                    devicePercentValue = (float) deviceCount / (float) deviceTotalCount;
                    presentValue += devicePercentValue;
                } else {
                    devicePercentValue = 1f - presentValue;
                }
                passMap.put("deviceName", deviceName);
                passMap.put("amountPercent", numberFormat.format(devicePercentValue));
                percentData.add(passMap);
            }
        }
        if (nameAndCountList.size() > 5) {
            Map<String, Object> passMap = new HashMap<>();
            passMap.put("deviceName", "其他");
            passMap.put("amountPercent", numberFormat.format(1f - presentValue));
            percentData.add(passMap);
        }
        //计算在线设备数量
        Integer onlineDeviceCount = resultIntercom.size() + resultElevator.size() + resultPad.size() + resultEntrance.size() + resultCluster.size() + resultWippen.size() + resultUnibodyFace.size();
        operateDeviceManageInfoAllVO.setDeviceCount(deviceTotalCount + "");
        operateDeviceManageInfoAllVO.setOnlineDevice(onlineDeviceCount + "");
        operateDeviceManageInfoAllVO.setOfflineDevice(deviceTotalCount - onlineDeviceCount + "");
        operateDeviceManageInfoAllVO.setPercentList(percentData);
        return operateDeviceManageInfoAllVO;

    }

    /**
     * <desc>
     *      修改设备的状态 删除、恢复
     * </desc>
     *
     * @param dto 参数DTO
     * @return
     * @author Juguang.S
     * @createDate 2020/12/02
     */
    public void modifyDeviceStatus(OperateDeviceManageGetPageDTO dto) throws Exception{

        Integer deviceType = Integer.parseInt(StringHandlerUtil.copySubStr(dto.getDeviceUnique(), 8, 1));
        String deviceUnique = dto.getDeviceUnique();
        String projectId = StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique);
        Map<String,Object> params = new HashMap<>();
        params.put("deviceUnique",dto.getDeviceUnique());
        params.put("status",dto.getStatus());
        JSONArray jsonArray = new JSONArray();
        JSONArray jsonArrayCloudElevator = new JSONArray();
        JSONArray jsonArrayCloudEntrance = new JSONArray();
        JSONArray jsonArrayCloudController = new JSONArray();
        JSONObject jsonObjectCloudEntance = new JSONObject();
        List<DeviceBusinessElevatorChangeLogPO> deviceBusinessChangeLogPOS = new ArrayList<>();
        List<DeviceBusinessEntranceChangeLogPO> deviceBusinessEntranceChangeLogPOS = new ArrayList<>();
        List<DeviceBusinessChangeLogPO> changeLogPOS = new ArrayList<>();
        List<String> userIdList =  new ArrayList<>();
        List<String> list = null;
        switch (PropertyEquipTypeEnum.getByEquipType(deviceType)) {
            case ELEVATOR:
                params.put("type",PropertyEquipTypeEnum.ELEVATOR.getType());
                DeviceElevatorInfoPO elevatorInfoPO = iPropertyElevatorDao.getByDeviceUnique(deviceUnique);
                //如果修改的是云电梯设备的状态则推送指令
                if (PropertyEquipTypeEnum.CLOUD_ELEVATOR.getType() == elevatorInfoPO.getElevatorType()){
                    JSONObject jsonObjectCloudElevator = new JSONObject();
                    jsonObjectCloudElevator.put("deviceUnique", deviceUnique);
                    jsonObjectCloudElevator.put("projectId", projectId);
                    jsonObjectCloudElevator.put("sn", elevatorInfoPO.getSn());
                    jsonArrayCloudElevator.add(jsonObjectCloudElevator);
                }
                list = getUserFaceInfo(deviceUnique,projectId);
                if(null != list) {
                    userIdList.addAll(list);
                }
                break;
            case ENTRANCE:
                params.put("type",PropertyEquipTypeEnum.ENTRANCE.getType());
                //如果修改的是云门禁设备的状态则推送指令
                if (PropertyEquipTypeEnum.ENTRANCE.getType() == Integer.parseInt(deviceUnique.substring(8,9))){
                    jsonObjectCloudEntance.put("deviceUnique", deviceUnique);
                    jsonObjectCloudEntance.put("projectId", projectId);
                    jsonObjectCloudEntance.put("sn", String.format("%s%s%s",projectId,"0000",deviceUnique.substring(9,deviceUnique.length())));
                }
                list = getUserFaceInfo(deviceUnique,projectId);
                if(null != list){
                    userIdList.addAll(list);
                }
                break;
            case CLOUD_INTERCOM:
                params.put("type",PropertyEquipTypeEnum.CLOUD_INTERCOM.getType());
                //状态发生变化时添加硬件推送指令
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("deviceUnique", deviceUnique);
                jsonArray.add(jsonObject);
                break;
            case PAD:
            case OUT_CALL_CONTROLLER:
            case CLOUD_PASS_RECORD_ELEVATOR:
                params.put("type",PropertyEquipTypeEnum.PAD.getType());
                break;
            case CLOUD_CONTROLLER:
                params.put("type",PropertyEquipTypeEnum.CLOUD_CONTROLLER.getType());
                Map<String,Object> paramsByCloudController = new HashMap<>();
                paramsByCloudController.put("deviceId",StringHandlerUtil.getDeviceIdByDeviceUnique(deviceUnique));
                paramsByCloudController.put("projectId",projectId);
                PropertyDeviceCloudControllerGetVO oneByDeviceId = iDeviceCloudControllerDao.getOne(paramsByCloudController);
                //向设备推送设备云电梯指令
                JSONObject jsonObjectCloudElevator = new JSONObject();
                jsonObjectCloudElevator.put("deviceUnique", deviceUnique);
                jsonObjectCloudElevator.put("projectId", projectId);
                jsonObjectCloudElevator.put("sn", oneByDeviceId.getSn());
                jsonArrayCloudController.add(jsonObjectCloudElevator);
                //向设备推送云群控器指令
                if (!jsonArrayCloudController.isEmpty()) {
                    DeviceBusinessElevatorChangeLogPO elevatorChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudController.toJSONString());
                    deviceBusinessChangeLogPOS.add(elevatorChangeLogPO);
                    //推送云群控器启指令
                    if(!deviceBusinessChangeLogPOS.isEmpty()){
                        this.pushElevator(deviceBusinessChangeLogPOS);
                    }
                }
                break;
            default:
        }
        iOperateDeviceManageDao.modifyDeviceStatus(params);
        //设备地址变更，存储变更后的地址信息，等待定时任务刷新权限
        TimeTaskAuthDeviceAddressInfoPO deviceAddrPO = dto.getTimeTaskAuthDeviceAddressInfoPO();
        if (deviceAddrPO != null && (deviceType != 5 && deviceType != 4)) {
            iTimeTaskAuthDeviceAddressInfoDao.save(SqlUtil.durableData(deviceAddrPO, PlatformConstants.TABLE_SAVE));
        }

        //向设备推送设备云对讲指令
        if (!jsonArray.isEmpty()) {
            DeviceBusinessChangeLogPO changeLogPO = new DeviceBusinessChangeLogPO(SmartCommunityEnum.PUSH_DEVICE, jsonArray, projectId);
            changeLogPOS.add(changeLogPO);
            //推送云对讲重启指令
            if(changeLogPOS != null && !changeLogPOS.isEmpty()){
                this.pushCloudIntercom(changeLogPOS);
            }
        }

        //向设备推送设备云电梯指令
        if (!jsonArrayCloudElevator.isEmpty()) {
            DeviceBusinessElevatorChangeLogPO elevatorChangeLogPO = new DeviceBusinessElevatorChangeLogPO(projectId, CloudElevatorChangeBusinessEnum.PUSH_DEVICE_INFO,jsonArrayCloudElevator.toJSONString());
            deviceBusinessChangeLogPOS.add(elevatorChangeLogPO);
            //推送云电梯重启指令
            if(deviceBusinessChangeLogPOS != null && !deviceBusinessChangeLogPOS.isEmpty()){
                this.pushElevator(deviceBusinessChangeLogPOS);
            }
        }
        //向云门禁推送设备指令
        if(!jsonObjectCloudEntance.isEmpty()){

            deviceBusinessEntranceChangeLogPOS.add(new DeviceBusinessEntranceChangeLogPO(CloudEntranceChangeBusinessEnum.PUSH_DEVICE_ONE, jsonObjectCloudEntance, projectId));
            if(deviceBusinessEntranceChangeLogPOS!=null && !deviceBusinessEntranceChangeLogPOS.isEmpty()){
                this.pushEntrance(deviceBusinessEntranceChangeLogPOS);
            }
        }

        //如果该项目启用了人脸识别才向c#发送增量处理
        if(userIdList!=null && iSmartCardFaceDao.isStartFaceByProjectId(projectId)>0){
            //发送C#人脸识别用户权限变更增量推送指令,先进行持久化，再由定时任务统一去处理 只有设备禁用启用时deviceUnique才不为空
            SmartCardFaceTimePullInfoPO timePullInfoPO = new SmartCardFaceTimePullInfoPO();
            timePullInfoPO.setPullId(LogicIdUtil.bussinessId());
            timePullInfoPO.setProjectId(projectId);
            timePullInfoPO.setDeviceUniqueInfo(deviceUnique);
            timePullInfoPO.setSyncStatus(1);
            timePullInfoPO.setUserIdInfo(Joiner.on(",").join(userIdList));
            timePullInfoPO.setStatus(dto.getStatus()==0?2:dto.getStatus());
            //由于权限更新需要一分钟，故此处为了保证权限最新故90秒后再进行定时任务下发增量数据
            timePullInfoPO.setAllowSyncTime(DateUtil.addSecond(new Date(), 90));
            timePullInfoPO.setCreateTime(new Date());
            iSmartCardFaceDao.save(SqlUtil.durableData(timePullInfoPO,PlatformConstants.TABLE_SAVE));
        }
    }

    /**
     * <desc>
     *      根据设备唯一码注册人脸的userId集合
     * <desc/>
     *
     * @author Juguang.S
     * @createDate 2019/03/20
     */
    public List<String> getUserFaceInfo(String deviceUnique,String projectId){
        List<Map<String,Object>> builds = iSmartCardFaceDao.getAddressByDeviceUnique(deviceUnique);
        List<String> userIdList = null;
        if(builds.size() > 1 ){
            //多楼栋
            List<String> bs = new ArrayList<>();
            builds.forEach(build->{
                bs.add(build.get("buildId").toString());
            });
            userIdList = iDeviceAddressUserInfoServiceDao.getUserInfosByBuilds(bs, projectId);
        }else if(builds.size() == 1 && builds.get(0).get("unitId")!=null){
            //多单元
            String[] unit = StringHandlerUtil.splitString(builds.get(0).get("unitId").toString());
            userIdList = iDeviceAddressUserInfoServiceDao.getUserInfosByUnits(unit, projectId);
        }
        return userIdList;
    }

    /**
     * <desc>
     *      向设备推送设备云电梯指令
     * <desc/>
     *
     * @param   changeLogPOS     云电梯变更指令集合
     * @author Jiaqi.X
     * @createDate 2017/12/1
     */
    public void pushElevator(List<DeviceBusinessElevatorChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云电梯
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ELEVATOR_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ELEVATOR_CHANGE_BUSINESS_ROUTING_KEY);
        }

    }

    /**
     * <desc>
     *      向设备推送设备云门禁指令
     * <desc/>
     *
     * @param   changeLogPOS     云门禁变更指令集合
     * @author Juguang.S
     * @createDate 2019/02/27
     */
    public void pushEntrance(List<DeviceBusinessEntranceChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云门禁
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_CLOUD_ENTRANCE_CHANGE_BUSINESS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_CLOUD_ENTRANCE_CHANGE_BUSINESS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     *      向设备推送设备云对讲指令
     * <desc/>
     *
     * @param   changeLogPOS     云对讲变更指令集合
     * @author Biao.R
     * @createDate 2017/12/1
     */
    public void pushCloudIntercom(List<DeviceBusinessChangeLogPO> changeLogPOS) throws Exception {
        // 添加硬件推送指令
        if (!changeLogPOS.isEmpty()) {
            JSONObject dataJs = new JSONObject();
            dataJs.put("data", changeLogPOS);
            //云对讲
            messageSender.send(RabbitMQConstant.RABBITMQ_HANDLE_SMART_COMMUNITY_ORDERS_QUEUE,
                    JsonUtil.toJSON(dataJs), RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_EXCHANGE,
                    RabbitMQConstant.RABBITMQ_SMART_COMMUNITY_ORDERS_ROUTING_KEY);
        }
    }

    /**
     * <desc>
     * 删除运行日志
     * </desc>
     *
     * @param runLogId 运行日志逻辑ID
     * @return Object
     * @author caoshuai
     * @createDate 2020/11/16 13:40
     */
    @Override
    public Integer delRunLog(String runLogId) {

        return iDeviceRunLogDao.delRunLogById(runLogId);
    }

    /**
     * <desc>
     * 运行日志列表
     * </desc>
     *
     * @param deviceUnique 设备ID
     * @return
     * @author caoshuai
     * @createDate 2020/11/16 13:40
     */
    @Override
    public Map<String, Object> getRunLogInfoPage(String deviceUnique, int pageSize, int currentPage, String orderRule) {
//        List<DeviceRunLogVO> deviceRunLogVOS = new ArrayList<>();
        Map<String, Object> result = new HashMap();
        /*//获取项目信息
        OperateDeviceDetailsVO operateDeviceDetailsVO = iOperateDeviceManageDao.getProjectInfoById(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));

        Integer deviceType = StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique);
        //获取设备信息
        Map<String, Object> deviceInfo = iOperateDeviceManageDao.getDeviceInfoById(deviceUnique, deviceType);

        operateDeviceDetailsVO.setDeviceName(deviceInfo.get("deviceName") == null ?  "" : deviceInfo.get("deviceName") + "");
        operateDeviceDetailsVO.setProductCode(deviceInfo.get("productCode") == null ?  "" : deviceInfo.get("productCode") + "");
        operateDeviceDetailsVO.setDeviceUnique(deviceUnique);*/

        Map<String, Object> params = new HashMap<>();
        params.put("deviceUnique", deviceUnique);
        params.put("status", "1");
        //分页类默认pageSize为20
        Page<DeviceRunLogVO> page = new Page<>();
        page.getPage().setPageSize(pageSize + "");
        page.getPage().setCurrentPage(currentPage + "");
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        params.put("orderRule", orderRule);

        List<DeviceRunLogVO> deviceRunLogVOS = iOperateDeviceManageDao.getPage(params);
        Integer total = iOperateDeviceManageDao.getPageTotal(params);

        page.setRows(deviceRunLogVOS, total);

        result.put("page", page);
//        result.put("operateDeviceDetailsVO", operateDeviceDetailsVO);

        return result;
    }

    /**
     * <desc>
     * 设备重启业务
     * </desc>
     *
     * @param deviceUnique 设备ID
     * @return
     * @author caoshuai
     * @createDate 2020/11/16 13:40
     */
    @Override
    public Integer restartDevice(String deviceUnique, String deviceTypeCode) throws Exception {
        Integer row = null;
        //设备类型
        Integer deviceType = StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique);
        //存库参数
        Map<String, Object> params;
        //云电梯 群控器
        if (deviceType.equals(1) || deviceType.equals(5)) {
            PushCloudElevatorChangeLogPO pushCloudElevatorChangeLogPO = new PushCloudElevatorChangeLogPO();
            pushCloudElevatorChangeLogPO.setDeviceUnique(deviceUnique);
            pushCloudElevatorChangeLogPO.setSn(StringHandlerUtil.getSnByDeviceUnique(deviceUnique));
            pushCloudElevatorChangeLogPO.setCommandStatus(0);
            pushCloudElevatorChangeLogPO.setCommandType(201);
            pushCloudElevatorChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudElevatorChangeLogPO.setStatus(1);
            pushCloudElevatorChangeLogPO.setCreateTime(new Date());
            //获取项目信息
            ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique), deviceUnique,
                    StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique));

            //获取指令数据
            String commandData = getCommandData("201");
            pushCloudElevatorChangeLogPO.setCommandData(commandData);
            //下发指令 并返回
            params = SqlUtil.durableData(pushCloudElevatorChangeLogPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            Map<String, Object> data = new HashMap<>();
            data.put("serviceId", "SettingService");
            data.put("commandName", "dataUpdate");
            data.put("deviceId", projectIotInfo.getHuaweiIotId());

            data.put("message", commandData);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", data);
            messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, JSON.toJSONString(jsonObject),
                    RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);


            // 创建延时队列将当前重启的设备信息存入延迟队列中，为后面新增重启失败日志做准备
            Map<String, Object> map = new HashMap<>();
            map.put("sn", StringHandlerUtil.getSnByDeviceUnique(deviceUnique));
            map.put("deviceUnique", deviceUnique);
            map.put("commandId", pushCloudElevatorChangeLogPO.getCommandId().trim());
            // 添加延时消息,PushCloudElevatorChangeLogMessage为     延时10分钟
            PushCloudChangeLogMessagePO PushCloudElevatorChangeLogMessage = new PushCloudChangeLogMessagePO(1, map, 600000);
            queue.getSendIotPushQueue().put(PushCloudElevatorChangeLogMessage);


        }

        //云门禁 联动器
        if (deviceType.equals(2)) {
            PushCloudEntranceChangeLogPO pushCloudEntranceChangeLogPO = new PushCloudEntranceChangeLogPO();
            pushCloudEntranceChangeLogPO.setDeviceUnique(deviceUnique);
            pushCloudEntranceChangeLogPO.setSn(StringHandlerUtil.getSnByDeviceUnique(deviceUnique));
            pushCloudEntranceChangeLogPO.setStatus(1);
            pushCloudEntranceChangeLogPO.setCommandStatus(0);
            pushCloudEntranceChangeLogPO.setCommandType(201);
            pushCloudEntranceChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudEntranceChangeLogPO.setCreateTime(new Date());
            ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique), deviceUnique,
                    StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique));
            //获取指令数据
            String commandData = getCommandData("201");
            pushCloudEntranceChangeLogPO.setCommandData(commandData);
            params = SqlUtil.durableData(pushCloudEntranceChangeLogPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            if ("7".equals(deviceTypeCode)) {
                //取得版本和iotkey
//                ProductTypePO productKey = iCloudTalkPushCloudIntercomChangeLogDao.getIntercomVersonIotkey(pushCloudEntranceChangeLogPO.getDeviceUnique());
                ProductTypePO productKey = iPushCloudEntranceChangeLogDao.getEntranceVersonIotkey(pushCloudEntranceChangeLogPO.getDeviceUnique());
                SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                        "/" + pushCloudEntranceChangeLogPO.getDeviceUnique() + "/user" + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), pushCloudEntranceChangeLogPO.getDeviceUnique(), "itlong", "2001", 1, pushCloudEntranceChangeLogPO.getCommandType().toString(), 1, 1);
                sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);

            } else {
                Map<String, Object> data = new HashMap<>();
                data.put("serviceId", "SettingService");
                data.put("commandName", "dataUpdate");
                String mainDeviceSn = iAppDeviceDao.getMainDeviceSnByDeviceUnique(deviceUnique);
                projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdBySn(mainDeviceSn), StringHandlerUtil.getEntranceDeviceUniqueBySn(mainDeviceSn),
                        2);

                data.put("deviceId", projectIotInfo.getHuaweiIotId());

                data.put("message", commandData);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data", data);
                messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, JSON.toJSONString(jsonObject),
                        RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);

            }
            // 创建延时队列将当前重启的设备信息存入延迟队列中，为后面新增重启失败日志做准备
            Map<String, Object> map = new HashMap<>();
            map.put("sn", StringHandlerUtil.getSnByDeviceUnique(deviceUnique));
            map.put("deviceUnique", deviceUnique);
            map.put("commandId", pushCloudEntranceChangeLogPO.getCommandId().trim());
            // 添加延时消息,PushCloudEntranceChangeLogMessage为     延时10分钟 LogicIdUtil.bussinessId()
            PushCloudChangeLogMessagePO PushCloudEntranceChangeLogMessage = new PushCloudChangeLogMessagePO(2, map, 600000);
            queue.getSendIotPushQueue().put(PushCloudEntranceChangeLogMessage);


        }
        //云对讲
        if (deviceType.equals(3)) {
            PushCloudIntercomChangeLogPO pushCloudIntercomChangeLogPO = new PushCloudIntercomChangeLogPO();
            pushCloudIntercomChangeLogPO.setDeviceUnique(deviceUnique);
            //获取 设备信息
            String sn = iDeviceRunLogDao.getIntercomSnByDeviceUnique(deviceUnique);
            pushCloudIntercomChangeLogPO.setSn(sn);
            pushCloudIntercomChangeLogPO.setCommandType(201);
            pushCloudIntercomChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudIntercomChangeLogPO.setStatus(1);
            pushCloudIntercomChangeLogPO.setCreateTime(new Date());
            params = SqlUtil.durableData(pushCloudIntercomChangeLogPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            ProductTypePO productKey = iOperateDeviceManageDao.getIntercomVersonIotkey(pushCloudIntercomChangeLogPO.getDeviceUnique());
            SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                    "/" + pushCloudIntercomChangeLogPO.getDeviceUnique() + "/user" + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), pushCloudIntercomChangeLogPO.getDeviceUnique(), "itlong", "2001", 1, pushCloudIntercomChangeLogPO.getCommandType().toString(), 1, 1);
            sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);


            // 创建延时队列将当前重启的设备信息存入延迟队列中，为后面新增重启失败日志做准备
            Map<String, Object> map = new HashMap<>();
            map.put("sn", sn);
            map.put("deviceUnique", deviceUnique);
            map.put("commandId", pushCloudIntercomChangeLogPO.getCommandId().trim());
            // 添加延时消息,PushCloudIntercomChangeLogMessage为     延时10分钟
            PushCloudChangeLogMessagePO PushCloudIntercomChangeLogMessage = new PushCloudChangeLogMessagePO(3, map, 600000);
            queue.getSendIotPushQueue().put(PushCloudIntercomChangeLogMessage);

        }
        //人脸
        if (deviceType.equals(4)) {
            PadPullCloudInfoPO padPullCloudInfoPO = new PadPullCloudInfoPO();
            padPullCloudInfoPO.setDeviceUnique(deviceUnique);
            padPullCloudInfoPO.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            padPullCloudInfoPO.setDataType(201);
            padPullCloudInfoPO.setSyncStatus(2);
            padPullCloudInfoPO.setStatus(1);
            padPullCloudInfoPO.setSyncType(2);
            padPullCloudInfoPO.setCreateTime(new Date());
            padPullCloudInfoPO.setSyncSerialNo(idWorker.nextId() + "");

            /*`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
              `device_unique` varchar(200) DEFAULT NULL COMMENT '平板设备唯一码',
              `project_id` varchar(50) DEFAULT NULL COMMENT '项目编号',
              `sync_data` mediumtext COMMENT '同步数据',
              `sync_type` int(11) DEFAULT NULL COMMENT '同步类型 1:全量 2：增量',
              `sync_serial_no` varchar(32) DEFAULT NULL COMMENT '同步流水号,用于确认数据是否同步成功',
              `data_type` int(11) DEFAULT NULL COMMENT '数据类型(1:用户信息变更 | 2:平板所属地址下所有用户的设备权限信息 | 3:楼层映射信息 | 4:升级信息)',
              `sync_status` int(11) DEFAULT NULL COMMENT '同步状态标志 1.待同步；2.同步中;3.同步结束;4.同步失败',
              `status` int(11) DEFAULT NULL COMMENT '数据状态 (0删除 1正常 2禁用)',*/
           /* pushCloudEntranceChangeLogPO.setDeviceUnique(deviceUnique);
            pushCloudEntranceChangeLogPO.setCommandStatus(1);
            pushCloudEntranceChangeLogPO.setCommandType(201);
            pushCloudEntranceChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudEntranceChangeLogPO.setStatus(1);
            pushCloudEntranceChangeLogPO.setCreateTime(new Date());*/
            params = SqlUtil.durableData(padPullCloudInfoPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);

            ProductTypePO productKey = iOperateDeviceManageDao.getPadVersonIotkey();
            SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                    "/" + padPullCloudInfoPO.getDeviceUnique() + "/user" + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), padPullCloudInfoPO.getDeviceUnique(), "itlong", "2", 1, padPullCloudInfoPO.getDataType().toString(), 1, 1);
            sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);


            // 创建延时队列将当前重启的设备信息存入延迟队列中，为后面新增重启失败日志做准备
            Map<String, Object> map = new HashMap<>();
            map.put("deviceUnique", deviceUnique);
            map.put("syncSerialNo", padPullCloudInfoPO.getSyncSerialNo().trim());
            // 添加延时消息,PadPullCloudInfoMessage为     延时10分钟
            PushCloudChangeLogMessagePO PadPullCloudInfoMessage = new PushCloudChangeLogMessagePO(4, map, 600000);
            queue.getSendIotPushQueue().put(PadPullCloudInfoMessage);


        }


        return row;
    }

    /**
     * <desc>
     * 获取设备日志业务
     * </desc>
     *
     * @param deviceUnique
     * @author caoshuai
     * @createDate 2020/11/25 15:36
     */
    @Override
    public Integer getDeviceLog(String deviceUnique, String deviceId, String deviceTypeCode) throws Exception {

        Integer row = null;
        //设备类型
        Integer deviceType = StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique);
        //存库参数
        Map<String, Object> params;
        //云电梯 群控器
        if (deviceType.equals(1) || deviceType.equals(5)) {
            PushCloudElevatorChangeLogPO pushCloudElevatorChangeLogPO = new PushCloudElevatorChangeLogPO();
            pushCloudElevatorChangeLogPO.setDeviceUnique(deviceUnique);
            pushCloudElevatorChangeLogPO.setCommandStatus(0);
            pushCloudElevatorChangeLogPO.setCommandType(200);
            pushCloudElevatorChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudElevatorChangeLogPO.setSn(StringHandlerUtil.getSnByDeviceUnique(deviceUnique));
            pushCloudElevatorChangeLogPO.setStatus(1);
            pushCloudElevatorChangeLogPO.setCreateTime(new Date());


            //获取项目信息
            ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique), deviceUnique,
                    StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique));

            params = SqlUtil.durableData(pushCloudElevatorChangeLogPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            Map<String, Object> data = new HashMap<>();
            data.put("serviceId", "SettingService");
            data.put("commandName", "dataUpdate");
            data.put("deviceId", projectIotInfo.getHuaweiIotId());
            //获取指令数据
            String commandData = getCommandData("200");
            data.put("message", commandData);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("data", data);
            messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, JSON.toJSONString(jsonObject),
                    RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);

        }

        //云门禁 联动器
        if (deviceType.equals(2)) {
            PushCloudEntranceChangeLogPO pushCloudEntranceChangeLogPO = new PushCloudEntranceChangeLogPO();
            pushCloudEntranceChangeLogPO.setDeviceUnique(deviceUnique);
            pushCloudEntranceChangeLogPO.setSn(StringHandlerUtil.getSnByDeviceUnique(deviceUnique));
            pushCloudEntranceChangeLogPO.setStatus(1);
            pushCloudEntranceChangeLogPO.setCommandStatus(0);
            pushCloudEntranceChangeLogPO.setCommandType(200);
            pushCloudEntranceChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudEntranceChangeLogPO.setCreateTime(new Date());

            ProjectIotInfo projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique), deviceUnique,
                    StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique));
            //获取推送指令数据
            String commandData = getCommandData("200");
            //指令存库数据
            Map<String, Object> commandDataMap = new HashMap<>(16);
            if (StringUtils.isNotBlank(deviceId)) {
                commandDataMap.put("doorNum", Integer.valueOf(deviceId) + "");
            }
            pushCloudEntranceChangeLogPO.setCommandData(JSON.toJSONString(commandDataMap));
            params = SqlUtil.durableData(pushCloudEntranceChangeLogPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            if ("7".equals(deviceTypeCode)) {
                //取得版本和iotkey
//                ProductTypePO productKey = iCloudTalkPushCloudIntercomChangeLogDao.getIntercomVersonIotkey(pushCloudEntranceChangeLogPO.getDeviceUnique());
                ProductTypePO productKey = iPushCloudEntranceChangeLogDao.getEntranceVersonIotkey(pushCloudEntranceChangeLogPO.getDeviceUnique());
                SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                        "/" + pushCloudEntranceChangeLogPO.getDeviceUnique() + "/user" + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), pushCloudEntranceChangeLogPO.getDeviceUnique(), "itlong", "2001", 1, pushCloudEntranceChangeLogPO.getCommandType().toString(), 1, 1);
                sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);

            } else {
                String mainDeviceSn = iAppDeviceDao.getMainDeviceSnByDeviceUnique(deviceUnique);
                projectIotInfo = iAppDeviceDao.getProjectIotInfoByProjectId(StringHandlerUtil.getProjectIdBySn(mainDeviceSn), StringHandlerUtil.getEntranceDeviceUniqueBySn(mainDeviceSn),
                        2);
                //发送指令
                Map<String, Object> data = new HashMap<>();
                data.put("serviceId", "SettingService");
                data.put("commandName", "dataUpdate");
                data.put("deviceId", projectIotInfo.getHuaweiIotId());
                //获取指令数据
                data.put("message", commandData);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("data", data);
                messageSender.send(RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_QUEUE, JSON.toJSONString(jsonObject),
                        RabbitMQConstant.RABBITMQ_IOT_PUB_EXCHANGE, RabbitMQConstant.RABBITMQ_HUAW_CALL_IOT_PUB_KEY);
            }


        }
        //云对讲
        if (deviceType.equals(3)) {
            //获取 设备信息
            String sn = iDeviceRunLogDao.getIntercomSnByDeviceUnique(deviceUnique);
            PushCloudIntercomChangeLogPO pushCloudIntercomChangeLogPO = new PushCloudIntercomChangeLogPO();
            pushCloudIntercomChangeLogPO.setDeviceUnique(deviceUnique);
            pushCloudIntercomChangeLogPO.setSn(sn);
            pushCloudIntercomChangeLogPO.setCommandType(200);
            pushCloudIntercomChangeLogPO.setCommandId(String.valueOf(idWorker.nextId()));
            pushCloudIntercomChangeLogPO.setStatus(1);
            pushCloudIntercomChangeLogPO.setCreateTime(new Date());

            Map<String, Object> commandData = new HashMap<>(16);
            commandData.put("sourceFrom", "itlong");
            commandData.put("snr", 1);
            commandData.put("cmd", "2001");
            Map<String, Object> data = new HashMap<>(16);
            data.put("commandType", "200");
            commandData.put("data", data);
            pushCloudIntercomChangeLogPO.setCommandData(JSON.toJSONString(commandData));
            params = SqlUtil.durableData(pushCloudIntercomChangeLogPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            ProductTypePO productKey = iOperateDeviceManageDao.getIntercomVersonIotkey(pushCloudIntercomChangeLogPO.getDeviceUnique());
            SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                    "/" + pushCloudIntercomChangeLogPO.getDeviceUnique() + "/user" + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), pushCloudIntercomChangeLogPO.getDeviceUnique(), "itlong", "2001", 1, pushCloudIntercomChangeLogPO.getCommandType().toString(), 1, 1);
            sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);

        }
        //人脸
        if (deviceType.equals(4)) {
            PadPullCloudInfoPO padPullCloudInfoPO = new PadPullCloudInfoPO();
            padPullCloudInfoPO.setDeviceUnique(deviceUnique);
            padPullCloudInfoPO.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
            padPullCloudInfoPO.setDataType(200);
            padPullCloudInfoPO.setSyncStatus(1);
            padPullCloudInfoPO.setStatus(1);
            padPullCloudInfoPO.setSyncType(2);
            padPullCloudInfoPO.setCreateTime(new Date());
            padPullCloudInfoPO.setSyncSerialNo(idWorker.nextId() + "");
            params = SqlUtil.durableData(padPullCloudInfoPO, PlatformConstants.TABLE_SAVE);
            //保存指令
            row = iOperateDeviceManageDao.save(params);
            ProductTypePO productKey = iOperateDeviceManageDao.getPadVersonIotkey();
            SendPushMessageTaskPO sendPushMessageTaskPO = new SendPushMessageTaskPO(productKey.getIotProductKey(),
                    "/" + padPullCloudInfoPO.getDeviceUnique() + "/user" + IotCloudCtrlInstructEnum.DEVICECMD.getUrl(), padPullCloudInfoPO.getDeviceUnique(), "itlong", "2", 1, padPullCloudInfoPO.getDataType().toString(), 1, 1);
            sendIotPushMessageQueue.getSendIotPushQueue().put(sendPushMessageTaskPO);

        }
        return row;

    }

    /**
     * <desc>
     * 获取详情
     * </desc>
     *
     * @param deviceUnique@return
     * @author caoshuai
     * @createDate 2020/11/25 15:36
     */
    @Override
    public OperateDeviceDetailsVO getDeviceDetails(String deviceUnique) {
        //获取项目信息
        OperateDeviceDetailsVO operateDeviceDetailsVO = iOperateDeviceManageDao.getProjectInfoById(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
        if (null == operateDeviceDetailsVO) {
            return operateDeviceDetailsVO;
        }
        Integer deviceType = StringHandlerUtil.getDeviceTypeByDeviceUnique(deviceUnique);
        //获取设备信息
        Map<String, Object> deviceInfo = iOperateDeviceManageDao.getDeviceInfoById(deviceUnique, deviceType);
        if (deviceInfo != null) {
            operateDeviceDetailsVO.setCreateTime(deviceInfo.get("createTime") == null ? "" : deviceInfo.get("createTime") + "");
            operateDeviceDetailsVO.setDeviceName(deviceInfo.get("deviceName") == null ? "" : deviceInfo.get("deviceName") + "");
            operateDeviceDetailsVO.setProductCode(deviceInfo.get("productCode") == null ? "" : deviceInfo.get("productCode") + "");
            operateDeviceDetailsVO.setCmdList(deviceInfo.get("cmdList") == null ? "" : deviceInfo.get("cmdList") + "");
            operateDeviceDetailsVO.setDeviceId(deviceInfo.get("deviceId") == null ? "" : deviceInfo.get("deviceId") + "");
            //设备类型:云门禁
            if (deviceType.equals(2)) {
                if ("22".equals(deviceInfo.get("entranceCategory") + "") || "25".equals(deviceInfo.get("entranceCategory") + "")) {
                    operateDeviceDetailsVO.setProductType("4");
                }
                if ("23".equals(deviceInfo.get("entranceCategory") + "")) {
                    operateDeviceDetailsVO.setProductType("6");
                }
                if ("24".equals(deviceInfo.get("entranceCategory") + "")) {
                    operateDeviceDetailsVO.setProductType("7");
                }
                if ("21".equals(deviceInfo.get("entranceCategory") + "")) {
                    operateDeviceDetailsVO.setProductType("9");
                }
                if ("25".equals(deviceInfo.get("entranceCategory") + "")) {//一体式云门禁
                    operateDeviceDetailsVO.setProductType("6");
                }
            }
            //设备类型:云电梯
            if (deviceType.equals(1)) {
                if ("11".equals(deviceInfo.get("elevatorType") + "")) {
                    operateDeviceDetailsVO.setProductType("9");
                }
                if ("12".equals(deviceInfo.get("elevatorType") + "")) {
                    operateDeviceDetailsVO.setProductType("2");
                }
            }
            //设备类型:云对讲
            if (deviceType.equals(3)) {
                operateDeviceDetailsVO.setProductType("1");
            }
            //设备类型:人脸平板
            if (deviceType.equals(4)) {
                operateDeviceDetailsVO.setProductType("3");
            }
            //设备类型:群控器
            if (deviceType.equals(5)) {
                operateDeviceDetailsVO.setProductType("5");
            }
            operateDeviceDetailsVO.setDeviceUnique(deviceUnique);
            String deviceActiveTime = redisService.getKeysForDevice(RedisConstant.DEVICE_NEW_UPDATE_CACHE_TIME + deviceUnique);
            if (null != deviceActiveTime && StringUtils.isNotBlank(deviceActiveTime)) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                operateDeviceDetailsVO.setDeviceActiveTime(simpleDateFormat.format(new Date(Long.valueOf(deviceActiveTime))));
            }
        }
        return operateDeviceDetailsVO;
    }

    /**
     * <desc>
     * 获取分页设备在线状态变更日志
     * </desc>
     *
     * @param deviceUnique
     * @param pageSize
     * @param currentPage
     * @return
     * @author caoshuai
     * @createDate 2020/11/25 9:23
     */
    @Override
    public Page getDeviceOnlineStatusAlterLogPage(String deviceUnique, int pageSize, int currentPage) {
        Map<String, Object> result = new HashMap<>();
        Map<String, Object> params = new HashMap<>();
        params.put("deviceUnique", deviceUnique);
        //分页类默认pageSize为20
        Page<DeviceOnlineStatusAlterLogPO> page = new Page<>();
        page.getPage().setPageSize(pageSize + "");
        page.getPage().setCurrentPage(currentPage + "");
        params.put("currentPage", page.getPage().getStartSlip());
        params.put("pageSize", page.getPage().getPageSize());
        List<DeviceOnlineStatusAlterLogPO> deviceOnlineStatusAlterLogPOS = iOperateDeviceManageDao.getDeviceOnlineStatusAlterLogPage(params);
        Integer total = iOperateDeviceManageDao.deviceOnlineStatusAlterLogTotal(params);
        page.setRows(deviceOnlineStatusAlterLogPOS, total);

        return page;
    }

    /**
     * <desc>
     * 保存操作日志信息
     * </desc>
     *
     * @param operationSpecialLog
     * @return
     * @author caoshuai
     * @createDate 2020/12/14 11:30
     */
    @Override
    public Integer saveOperationSpecialLog(OperationSpecialLogPO operationSpecialLog) throws Exception {


        return iOperateDeviceManageDao.save(SqlUtil.durableData(operationSpecialLog, PlatformConstants.TABLE_SAVE));
    }

    /**
     * <desc>
     * 获取用户信息
     * </desc>
     *
     * @param myUserName
     * @return
     * @author caoshuai
     * @createDate 2020/12/14 11:30
     */
    @Override
    public OperateUserInfoPO getOperateUserPO(String myUserName) {

        return iOperateDeviceManageDao.getOperateUserPO(myUserName);
    }

    /**
     * <desc>
     * 获取设备的开门方式占比
     * </desc>
     *
     * @param deviceUnique 设备唯一码
     * @return
     * @Author Zhu.yj
     * @createDate 2020/12/23
     */
    @Override
    public List<OperatePassPercentVO> getOpenPercent(String deviceUnique) throws Exception {
        List<OperatePassPercentVO> percentVOS = new ArrayList<>();
        NumberFormat numberFormat = NumberFormat.getInstance();
        NumberFormat numberFormatPercent = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(4);
        numberFormatPercent.setMaximumFractionDigits(2);
        List<Map<String, Object>> openCountList = iOperateDeviceManageDao.getOpenCount(deviceUnique);
        if (openCountList.isEmpty()) {
            return null;
        }
        int totalCount = Integer.parseInt(openCountList.get(0).get("count").toString());
        double currentPercent = 0.0;
        for (int i = 1; i < openCountList.size(); i++) {
            OperatePassPercentVO operatePassPercentVO = new OperatePassPercentVO();
            int count = Integer.parseInt(openCountList.get(i).get("count").toString());
            operatePassPercentVO.setCount(count);
            operatePassPercentVO.setOpenType(Integer.parseInt(openCountList.get(i).get("openType").toString()));
            //最后一种通行方式使用1- 防止百分比相加不等于1的情况
            if (i == openCountList.size() - 1) {
                operatePassPercentVO.setPercent(numberFormatPercent.format(1 - currentPercent));
            } else {
                double percent = (double) count / (double) totalCount;
                currentPercent += Double.parseDouble(numberFormat.format(percent));
                operatePassPercentVO.setPercent(numberFormatPercent.format(percent));
            }
            percentVOS.add(operatePassPercentVO);
        }
        return percentVOS;
    }

    /**
     * <desc>
     * 华为下发指令
     * </desc>
     *
     * @param
     * @return
     * @author caoshuai
     * @createDate 2020/11/25 15:25
     */
    private String getCommandData(String commandType) throws Exception {

        Map<String, Object> message = new HashMap<>();

        message.put("sourceFrom", "itlong");
        message.put("snr", LogicIdUtil.userBusinessId());
        message.put("cmd", "2001");
        message.put("timestamp", (System.currentTimeMillis() + 20000) + "");
        message.put("commandType", commandType);


        return JSON.toJSONString(message);
    }


    /**
     * <desc>
     * 查询云设备的推送指令
     * </desc>
     *
     * @param params
     * @Author chengshican
     * @Date 2020-12-29 13:51
     * @Param tableName 数据库表名 ， sn 设备sn
     * @Return commandStatus 命令处理状态,  updateTime 更新时间,  createTime 创建时间
     * @Exception
     */
    @Override
    public Map<String, Object> getPushCloudChangeLog(Map<String, Object> params) {
        return iOperateDeviceManageDao.getPushCloudChangeLog(params);
    }

    /**
     * <desc>
     * 定时从设备获取日志
     * </desc>
     *
     * @author maju
     * @createDate 2021/4/27
     */
    @Override
    public void getDeviceLogByTask() {
        OperateDeviceManageGetPageDTO dto = new OperateDeviceManageGetPageDTO();
        dto.setIsOnline("1");
        int page = 1;
        while (true) {
            try {
                dto.setCurrentPage(page + "");
                OperateDeviceManageInfoAllVO onLineDevice = getDeviceByPage(dto);
                //在线设备
                if (null == onLineDevice || null == onLineDevice.getPage() || CollectionUtils.isEmpty(onLineDevice.getPage().getRows())) {
                    break;
                }
                List<OperateDeviceManageInfoVO> rows = onLineDevice.getPage().getRows();
                for (OperateDeviceManageInfoVO row : rows) {
                    //触发获取设备日志接口
                    getDeviceLog(row.getDeviceUnique(), row.getDeviceId(), row.getDeviceType());
                    LOG.info("获取设备日志成功！,deviceUnique:{}", row.getDeviceUnique());
                }
                page++;
            } catch (Exception e) {
                LOG.info("获取设备日志失败！{}", e.getMessage());
                break;
            }
        }

    }

    /***
     * <desc>
     *      定时下载设备日志
     * </desc>
     *
     *
     * @author maju
     * @createDate 2021/4/27
     */
    @Override
    public void downloadDeviceLogByTask() {
        Set<Integer> ids = (Set<Integer>) redisService.getObject(RedisConstant.DEVICE_LOG_DOWNLOAD_ID_KEY, Set.class);
        if (CollectionUtils.isEmpty(ids)) {
            ids = new HashSet<>();
        }
        Set<Integer> downloads = new HashSet<>();
        //查询当天未下载日志
        List<DeviceRunLogPO> list = iDeviceRunLogDao.getDeviceRunLogInfoToDay(ids);
        if (!CollectionUtils.isEmpty(list)) {
            for (DeviceRunLogPO d : list
            ) {
                String fileName = d.getFileName();
                //下载日志
                boolean res = iIotAliOSSServiceClient.downloadFile(fileName, DEVICE_LOG);
                if (res) {
                    downloads.add(d.getId());
                }
            }
        }
        if (!CollectionUtils.isEmpty(downloads)) {
            ids.addAll(downloads);
            redisService.set(RedisConstant.DEVICE_LOG_DOWNLOAD_ID_KEY,RedisConstant.DEVICE_LOG_DOWNLOAD_ID_KEY_TIME,ids);
        }
    }


    @PostConstruct
    public void init() {

        OperationSpecialLogPO operationSpecialLogPO = new OperationSpecialLogPO();
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        PushCloudChangeLogMessagePO messagePO = queue.getSendIotPushQueue().take();
                        LOG.info("=====触发设备重启失败的业务操作日志===============》{}", messagePO.getBody());
                        if (messagePO.getBody() != null) {
                            String deviceUnique = messagePO.getBody().get("deviceUnique") + "";
                            String deviceType = deviceUnique.substring(8, 9);
                            LOG.info("=====触发设备重启失败的业务操作日志==deviceType=============》{}", deviceType);
                            switch (deviceType) {
                                case "1":
                                    Map<String, Object> elevatorMap = new HashMap<>();
                                    elevatorMap.put("tableName", "push_cloud_elevator_change_log");
                                    elevatorMap.put("sn", messagePO.getBody().get("sn") + "");
                                    elevatorMap.put("deviceUnique", messagePO.getBody().get("deviceUnique") + "");
                                    elevatorMap.put("commandId", messagePO.getBody().get("commandId") + "");
                                    Map<String, Object> pushCloudChangeLog = iOperateDeviceManageDao.getPushCloudChangeLog(elevatorMap);
                                    String commandStatus = pushCloudChangeLog.get("commandStatus") + "";
                                    String updateTime = pushCloudChangeLog.get("updateTime") + "";
                                    String createTime = pushCloudChangeLog.get("createTime") + "";
                                    //1.指令状态为 处理中 ，更新时间为null
                                    if (("1".equals(commandStatus) || "0".equals(commandStatus)) && "null".equals(updateTime)) {
                                        operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                        operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");

                                        //2.指令状态为 处理中 ，更新时间不为 null
                                    } else if (("1".equals(commandStatus) || "0".equals(commandStatus)) && !"null".equals(updateTime)) {
                                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        long minutes = 0L;
                                        Date d1 = df.parse(updateTime);
                                        Date d2 = df.parse(createTime);
                                        long diff = d1.getTime() - d2.getTime();// 这样得到的差值是微秒级别
                                        minutes = diff / (1000 * 60);
                                        if (minutes >= 10) {
                                            operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                            operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        }

                                    }
                                    break;
                                case "2":
                                    Map<String, Object> entranceMap = new HashMap<>();
                                    entranceMap.put("tableName", "push_cloud_entrance_change_log");
                                    entranceMap.put("sn", messagePO.getBody().get("sn") + "");
                                    entranceMap.put("deviceUnique", messagePO.getBody().get("deviceUnique") + "");
                                    entranceMap.put("commandId", messagePO.getBody().get("commandId") + "");
                                    Map<String, Object> cloudChangeLog = iOperateDeviceManageDao.getPushCloudChangeLog(entranceMap);

                                    String entranceCommandStatus = cloudChangeLog.get("commandStatus") + "";
                                    String entranceUpdateTime = cloudChangeLog.get("updateTime") + "";
                                    String entranceCreateTime = cloudChangeLog.get("createTime") + "";
                                    //1.指令状态为 处理中 ，更新时间为null
                                    if (("1".equals(entranceCommandStatus) || "0".equals(entranceCommandStatus)) && "null".equals(entranceUpdateTime)) {
                                        operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                        operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        //2.指令状态为 处理中 ，更新时间不为 null
                                    } else if (!"null".equals(entranceUpdateTime) && ("1".equals(entranceCommandStatus) || "0".equals(entranceCommandStatus))) {
                                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        long minutes = 0L;
                                        Date d1 = df.parse(entranceUpdateTime);
                                        Date d2 = df.parse(entranceCreateTime);
                                        long diff = d1.getTime() - d2.getTime();// 这样得到的差值是微秒级别
                                        minutes = diff / (1000 * 60);
                                        if (minutes >= 10) {
                                            operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                            operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        }

                                    }
                                    break;
                                case "3":
                                    Map<String, Object> intercomMap = new HashMap<>();
                                    intercomMap.put("tableName", "push_cloud_intercom_change_log");
                                    intercomMap.put("sn", messagePO.getBody().get("sn") + "");
                                    intercomMap.put("deviceUnique", messagePO.getBody().get("deviceUnique") + "");
                                    intercomMap.put("commandId", messagePO.getBody().get("commandId") + "");
                                    Map<String, Object> intercomChangeLog = iOperateDeviceManageDao.getPushCloudChangeLog(intercomMap);
                                    String intercomCommandStatus = intercomChangeLog.get("commandStatus") + "";
                                    String intercomUpdateTime = intercomChangeLog.get("updateTime") + "";
                                    String intercomCreateTime = intercomChangeLog.get("createTime") + "";
                                    //1.指令状态为 处理中 ，更新时间为null
                                    if (("1".equals(intercomCommandStatus) || "0".equals(intercomCommandStatus)) && "null".equals(intercomUpdateTime)) {
                                        operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                        operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        //2.指令状态为 处理中 ，更新时间不为 null
                                    } else if (("1".equals(intercomCommandStatus) || "0".equals(intercomCommandStatus)) && !"null".equals(intercomUpdateTime)) {
                                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        long minutes = 0L;
                                        Date d1 = df.parse(intercomUpdateTime);
                                        Date d2 = df.parse(intercomCreateTime);
                                        long diff = d1.getTime() - d2.getTime();// 这样得到的差值是微秒级别
                                        minutes = diff / (1000 * 60);
                                        if (minutes >= 10) {
                                            operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                            operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        }

                                    }

                                    break;
                                case "4":
                                    Map<String, Object> padMap = new HashMap<>();
                                    padMap.put("deviceUnique", messagePO.getBody().get("deviceUnique") + "");
                                    padMap.put("syncSerialNo", messagePO.getBody().get("syncSerialNo") + "");
                                    Map<String, Object> padPullCloudInfo = iOperateDeviceManageDao.getPadPullCloudInfo(padMap);
                                    String syncStatus = padPullCloudInfo.get("syncStatus") + "";
                                    String padUpdateTime = padPullCloudInfo.get("updateTime") + "";
                                    String padCreateTime = padPullCloudInfo.get("createTime") + "";
                                    //1.指令状态为 处理中 ，更新时间为null
                                    if (("2".equals(syncStatus) || "1".equals(syncStatus)) && "null".equals(padUpdateTime)) {
                                        operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                        operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        //2.指令状态为 处理中 ，更新时间不为 null
                                    } else if (("2".equals(syncStatus) || "1".equals(syncStatus)) && !"null".equals(padUpdateTime)) {
                                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        long minutes = 0L;
                                        Date d1 = df.parse(padUpdateTime);
                                        Date d2 = df.parse(padCreateTime);
                                        long diff = d1.getTime() - d2.getTime();// 这样得到的差值是微秒级别
                                        minutes = diff / (1000 * 60);
                                        if (minutes >= 10) {
                                            operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                            operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        }

                                    }
                                    break;
                                case "5":
                                    Map<String, Object> controllerMap = new HashMap<>();
                                    controllerMap.put("tableName", "push_cloud_elevator_change_log");
                                    controllerMap.put("sn", messagePO.getBody().get("sn") + "");
                                    controllerMap.put("deviceUnique", messagePO.getBody().get("deviceUnique") + "");
                                    controllerMap.put("commandId", messagePO.getBody().get("commandId") + "");
                                    Map<String, Object> controllerCloudChangeLog = iOperateDeviceManageDao.getPushCloudChangeLog(controllerMap);
                                    String controllerCommandStatus = controllerCloudChangeLog.get("commandStatus") + "";
                                    String controllerUpdateTime = controllerCloudChangeLog.get("updateTime") + "";
                                    String controllerCreateTime = controllerCloudChangeLog.get("createTime") + "";
                                    //1.指令状态为 处理中 ，更新时间为null
                                    if (("1".equals(controllerCommandStatus) || "0".equals(controllerCommandStatus)) && "null".equals(controllerUpdateTime)) {
                                        operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                        operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        //2.指令状态为 处理中 ，更新时间不为 null
                                    } else if (("1".equals(controllerCommandStatus) || "0".equals(controllerCommandStatus)) && !"null".equals(controllerUpdateTime)) {
                                        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                        long minutes = 0L;
                                        Date d1 = df.parse(controllerUpdateTime);
                                        Date d2 = df.parse(controllerCreateTime);
                                        long diff = d1.getTime() - d2.getTime();// 这样得到的差值是微秒级别
                                        minutes = diff / (1000 * 60);
                                        if (minutes >= 10) {
                                            operationSpecialLogPO.setOuterId(messagePO.getBody().get("deviceUnique") + "");
                                            operationSpecialLogPO.setOperateDec("系统重启设备失败！设备sn:" + messagePO.getBody().get("sn") + "" + "。");
                                        }
                                    }
                                    break;
                            }
                            Date nowTime = new Date();
                            operationSpecialLogPO.setLogId(LogicIdUtil.bussinessId());
                            operationSpecialLogPO.setRealName("系统");
                            operationSpecialLogPO.setAccount("系统");
                            operationSpecialLogPO.setIp("");
                            operationSpecialLogPO.setOperateFunction("重启");
                            operationSpecialLogPO.setOperateWay("重启");
                            operationSpecialLogPO.setFunctionType(8);
                            operationSpecialLogPO.setStatus(DataStatusEnum.NORMAL.getType());
                            operationSpecialLogPO.setCreateTime(nowTime);
                            operationSpecialLogPO.setUpdateTime(nowTime);
                            LOG.info("=====触发设备重启失败的业务操作日志======当前数据的时间============》{}", nowTime);
                            iOperateDeviceManageDao.save(SqlUtil.durableData(operationSpecialLogPO, PlatformConstants.TABLE_SAVE));
                            LOG.info("=====触发设备重启失败的业务操作日志======成功============》{}", operationSpecialLogPO);
                        }

                    } catch (InterruptedException e) {
                        LOG.info("=====触发设备重启失败的业务操作日志=失败==============》{}", e);
                        e.printStackTrace();
                    } catch (Exception e) {
                        LOG.info("=====触发设备重启失败的业务操作日志=失败==============》{}", e);
                        e.printStackTrace();
                    }
                }
            }
        });

    }
}
